package com.example.onlinemusic.controller;

import com.example.onlinemusic.mapper.LoveMusicMapper;
import com.example.onlinemusic.mapper.MusicMapper;
import com.example.onlinemusic.model.Music;
import com.example.onlinemusic.model.User;
import com.example.onlinemusic.tools.Constant;
import com.example.onlinemusic.tools.ResponseBodyMessage;
import org.jaudiotagger.audio.exceptions.CannotReadException;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
import org.jaudiotagger.tag.TagException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.jws.soap.SOAPBinding;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/music")
public class MusicController {

    @Value("${music.local.path}")
    private String SAVE_PATH;

    @Autowired
    private MusicMapper musicMapper;
    @Autowired
    private LoveMusicMapper loveMusicMapper;

    /**
     * 上传音乐
     * @param singer
     * @param filename
     * @param request
     * @return
     * @throws CannotReadException
     * @throws TagException
     * @throws InvalidAudioFrameException
     * @throws ReadOnlyFileException
     * @throws IOException
     */
    @RequestMapping("/upload")
    public ResponseBodyMessage<Boolean> upload(@RequestParam String singer, @RequestParam("filename")MultipartFile filename, HttpServletRequest request) throws CannotReadException, TagException, InvalidAudioFrameException, ReadOnlyFileException, IOException {

        HttpSession session = request.getSession(false);
        if(session == null || session.getAttribute(Constant.USERINFO_SESSION_KEY) == null) {
            return new ResponseBodyMessage<>(-1,"未登录",false);
        }


        //得到文件源名称(得到文件保存位置)
        String fileNameAndType = filename.getOriginalFilename();
        //得到出去文件后缀的名称(歌名)
        String title = fileNameAndType.substring(0,fileNameAndType.lastIndexOf("."));
        //判断上传文件是否已经存在(歌名+歌手名)
        //数据库查询是否存在
        //判断数据库返回是否为null
        Music music = musicMapper.repeatMusic(title,singer);

        if(music != null) {
            return new ResponseBodyMessage<>(-2,"已存在该歌曲",false);
        }


        //编写文件上传路径
        String path = SAVE_PATH + "/" + fileNameAndType;
        //将上传路径作为文件保存位置(创建一个新文件)
        File dest = new File(path);
        //判断该文件是否存在
        if(!dest.exists()) {
            dest.mkdir();
        }
//        //将文件转为MP3格式
//        MP3File mp3File = (MP3File) AudioFileIO.read(dest);
//        //判断MP3文件中是否包含有Tag
//        if(!mp3File.hasID3v1Tag()) {
//            return new ResponseBodyMessage<>(-1,"不是MP3文件",false);
//        }


        //将文件上传到新位置
        try {
            filename.transferTo(dest);
            //本地上传成功后等数据库上传后做统一的返回处理
            // return new ResponseBodyMessage<>(0,"上传成功",true);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseBodyMessage<>(-1,"上传失败",false);

        }

        //为上传数据库做准备,获取music表中的数据
        //id自增
        //title(在获取文件名处已经处理)
        //singer在请求参数中包含
        //time
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy--MM--dd");
        String time = simpleDateFormat.format(new Date());
        //url
        String url = "/music/get?path=" + title;
        //userid
        User user = (User) session.getAttribute(Constant.USERINFO_SESSION_KEY);
        System.out.println("用户姓名" + user.getUsername());
        int userid = user.getId();

        //插入数据库
        int ret = musicMapper.insert(title,singer,time,url,userid);

        if(ret == 1) {
            return new ResponseBodyMessage<>(0,"上传成功",true);
        }else {
            return new ResponseBodyMessage<>(-1,"上传失败",false);
        }

    }

    /**
     * 播放音乐功能
     * @param path
     * @return
     */
    @RequestMapping("/get")
    public ResponseEntity<byte[]> get(String path){

//        Music music = musicMapper.selectMusic(path);
//        if(music == null) {
//            return ResponseEntity.notFound().build();
//        }

        File file = new File(SAVE_PATH + "/" + path);
        byte[] allByte = null;
        try {
            allByte = Files.readAllBytes(file.toPath());
            if(allByte == null) {
                return ResponseEntity.badRequest().build();
            }else {
                return ResponseEntity.ok(allByte);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseEntity.internalServerError().build();
    }


    /**
     * 删除单个音乐
     * @param id
     * @return
     */
    @RequestMapping("/delete")
    public ResponseBodyMessage<Boolean> deleteMusicById(@RequestParam int id,HttpServletRequest request) {

        HttpSession session = request.getSession(false);
        if(session == null || session.getAttribute(Constant.USERINFO_SESSION_KEY) == null) {
            return new ResponseBodyMessage<>(-1,"未登录",false);
        }

        User user = (User) session.getAttribute(Constant.USERINFO_SESSION_KEY);

        //根据id在数据库中查找是否存在次id
        //存在删除，不存在则返回

        Music music = musicMapper.findMusicById(id);
        if(music != null) {
            int ret = musicMapper.deleteMusicById(id);
            if(ret == 1) {
                //删除服务器上的文件
                String filename = music.getTitle();
                File file = new File(SAVE_PATH + "/" + filename + ".mp3");
                if(file.delete()) {

                    //删除歌曲的同时删除收藏的音乐
                    int num = loveMusicMapper.deleteLoveMusic(user.getId(),id);
                    if (num == 1) {
                        return new ResponseBodyMessage<>(0,"数据库与服务器上音乐删除成功,并且删除收藏的音乐的",true);
                    }
                    return new ResponseBodyMessage<>(0,"数据库与服务器上音乐删除成功",true);

                }
                return new ResponseBodyMessage<>(0,"数据库删除成功",true);

            }else {
                return new ResponseBodyMessage<>(-2,"数据库删除失败",false);
            }
        }else {
            return new ResponseBodyMessage<>(-1,"不存在id为" + id + "的歌曲",false);
        }
    }

    /**
     * 批量删除歌曲
     * @param id
     * @return
     */
    @RequestMapping("/deleteSel")
    public ResponseBodyMessage<Boolean> deleteSel(@RequestParam("id[]") List<Integer> id) {
        //先查后删
        //数组遍历
        int sum = 0;
        for (int i = 0; i < id.size(); i++) {
            Music music = musicMapper.findMusicById(id.get(i));
            if(music != null) {
                int ret = musicMapper.deleteMusicById(id.get(i));
                if(ret == 1) {
                    File file = new File(SAVE_PATH + "/" + music.getTitle() + ".mp3");
                    if(file.delete()) {
                        sum += ret;
                    }else {
                        return new ResponseBodyMessage<>(-1,"id为" + id.get(i) + "歌曲在服务器未删除",false);
                    }
                }else {
                    return new ResponseBodyMessage<>(-2,"id为" + id.get(i) + "歌曲在数据库未删除",false);
                }
            }else {
                return new ResponseBodyMessage<>(-3,"id为"+ id.get(i) +"歌曲不存在",false);
            }
        }
        if(sum == id.size()) {
            return new ResponseBodyMessage<>(0,"数据库与服务器上音乐均删除成功",true);
        }else {
            return new ResponseBodyMessage<>(-4,"一些歌曲在服务器未删除",false);
        }

    }


    /**
     * 查询音乐
     * @param musicName
     * @return
     */
    @RequestMapping("/findmusic")
    public ResponseBodyMessage<List<Music>> findMusic(@RequestParam(required = false)String musicName) {

        List<Music> musicList = null;
        if(musicName == null) {
            musicList = musicMapper.findMusic();

        }else {
            musicList = musicMapper.findMusicByName(musicName);

        }
        return new ResponseBodyMessage<>(0,"查询到全部音乐", musicList);
    }


    /**
     * 测试接口
     * @return
     */
    @RequestMapping("/play")
    public ResponseBodyMessage<String> play() {

        return new ResponseBodyMessage<>(1,"运行播放","https://music.163.com/#/song?id=2014348484");
    }

}
